package com.laolang.shop.modules.auth.util;

import cn.hutool.core.util.StrUtil;
import com.laolang.shop.common.core.consts.ModuleNameConst;
import com.laolang.shop.common.core.exception.BusinessException;
import com.laolang.shop.common.core.util.LogUtil;
import com.laolang.shop.modules.auth.config.JwtProperty;
import com.laolang.shop.modules.auth.entity.TokenUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author khlbat
 * @version 1.0
 * @date 2020/11/1 20:46
 */
@Slf4j
@Component
public class JwtTokenUtil {

    private static final String USER_ID_KEY = "userId";
    private static final String TENANT_ID_KEY = "tenantId";
    private static final String PHONE_KEY = "phone";


    @Autowired
    private JwtProperty jwtProperty;


    public String createToken(TokenUser user) {
        Map<String, Object> claimsMap = new HashMap<>();
        claimsMap.put(USER_ID_KEY, user.getUserId());
        claimsMap.put(TENANT_ID_KEY, user.getUserId());
        claimsMap.put(PHONE_KEY, user.getPhone());

        long now = System.currentTimeMillis();
        return Jwts.builder()
                .setClaims(claimsMap)
                // jwt 身份唯一标示
                // jti
                .setId(UUID.randomUUID().toString())
                // jwt 所面向的用户
                // sub
                .setSubject(String.valueOf(user.getUserId()))
                // 签发时间
                // iat
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, jwtProperty.getSecret())
                // 过期时间
                // exp
                .setExpiration(new Date(now + jwtProperty.getExpiration() * 1000))
                .compact();
    }

    public TokenUser getAuthUser(String token) {
        TokenUser authUser = null;
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(jwtProperty.getSecret())
                    .parseClaimsJws(token)
                    .getBody();
            authUser = new TokenUser();
            authUser.setPhone(claims.get(PHONE_KEY).toString());
            authUser.setUserId(Long.valueOf(claims.get(USER_ID_KEY).toString()));
            authUser.setTenantId(Long.valueOf(claims.get(TENANT_ID_KEY).toString()));
        } catch (Exception e) {
            LogUtil.error(log, ModuleNameConst.AUTH, StrUtil.format("解析token出错,token: {}\n e:{}", token, e.getMessage()));
            throw new BusinessException("解析token出错");
        }
        return authUser;
    }

    public Long getUserId(String token) {
        TokenUser authUser = getAuthUser(token);
        return null == authUser ? null : authUser.getUserId();
    }
}
